home *** CD-ROM | disk | FTP | other *** search
/ Enigma Amiga Life 109 / EnigmaAmiga109CD.iso / dalla rivista / amiga.free / sorgenti vari / wolf3dmacsource.sit / Wolf3DMacSource / PlMove.c < prev    next >
C/C++ Source or Header  |  1994-09-15  |  6KB  |  220 lines

  1. #include "wolfdef.h"
  2.  
  3. /**********************************
  4.  
  5.     See if players current position is ok
  6.     returns True if move ok
  7.     All coordinates are stored in 8.8 fractions (8 bits integer, 8 bits fraction)
  8.         
  9. **********************************/
  10.  
  11. static Boolean TryMove(Word Checkx,Word Checky)
  12. {
  13.     actor_t *ActorPtr;    /* Pointer to actor record */
  14.     Word xl,yl,xh,yh;    /* Rect to scan */
  15.     Word tile;    /* Tile being tested */
  16.     Word x,y;    /* Working x,y */
  17.  
  18.     xl = (Checkx - PLAYERSIZE)>>FRACBITS;    /* Make the rect for the player in tiles */
  19.     xh = ((Checkx + PLAYERSIZE)>>FRACBITS)+1;
  20.     yl = (Checky - PLAYERSIZE)>>FRACBITS;
  21.     yh = ((Checky + PLAYERSIZE)>>FRACBITS)+1;
  22.     
  23. /* check for solid walls*/
  24.  
  25.     y = yl;
  26.     do {
  27.         x=xl;
  28.         do {
  29.             tile = tilemap[y][x];    /* Test the tile */
  30.             if (tile & TI_GETABLE) {    /* Can I get this? */
  31.                 GetBonus(x,y);        /* Get the item */
  32.             }
  33.             if (tile & TI_BLOCKMOVE) {    /* Motion blocked */
  34.                 return FALSE;        /* Can't go this way! */
  35.             }
  36.         } while (++x<xh);    /* Scan the x */
  37.     } while (++y<yh);        /* Scan the y */
  38.  
  39. /* check for actors */
  40.  
  41.     yl--;    /* Increase the rect for actor hits */
  42.     yh++;
  43.     xl--;
  44.     xh++;
  45.     y = yl;
  46.     do {
  47.         x = xl;
  48.         do {    
  49.             tile = tilemap[y][x];    /* Get the tile */
  50.             if (tile&TI_ACTOR) {    /* Actor here? */
  51.                 ActorPtr = &actors[MapPtr->tilemap[y][x]];
  52.                 if (w_abs(ActorPtr->x - Checkx) < MINACTORDIST) {
  53.                     if (w_abs(ActorPtr->y - Checky) < MINACTORDIST)
  54.                         return FALSE;        /* I hit the actor! */
  55.                 }
  56.             }
  57.         } while (++x<xh);        /* Scan the x */
  58.     } while (++y<yh);            /* Scan the y */
  59.     playermoving = TRUE;        /* I am moving (Harder to hit) */
  60.     return TRUE;                /* Way is clear */
  61. }
  62.  
  63. /**********************************
  64.  
  65.     Clip the player's motion
  66.     I will also try to use as much motion as I have
  67.         
  68. **********************************/
  69.  
  70. static void ClipMove(int xmove,int ymove)
  71. {
  72.     int Checkx,Checky;
  73.  
  74. /* Try complete move */
  75.  
  76.     Checkx = xmove;        /* Save the current motion offset */
  77.     Checky = ymove;
  78.     do {
  79.         if (TryMove(actors[0].x+Checkx,actors[0].y+Checky)) {    /* Can I move here? */
  80.             actors[0].x += Checkx;    /* Save it */
  81.             actors[0].y += Checky;
  82.             if (Checkx==xmove) {    /* Use all the motion? */
  83.                 return;                /* Exit now! */
  84.             }
  85.             xmove-=Checkx;    /* Remove the used motion */
  86.             ymove-=Checky;
  87.             break;            /* Exit now */
  88.         }
  89.         if (Checkx==-1) {    /* Minimum motion */
  90.             Checkx = 0;
  91.         }
  92.         Checkx>>=1;        /* Reduce the amount of motion */
  93.         if (Checky==-1) {    /* Minimum motion */
  94.             Checky=0;
  95.         }
  96.         Checky>>=1;
  97.     } while (Checkx || Checky);    /* Is there ANY motion? */
  98.     
  99. /* Try horizontal motion */
  100.  
  101.     Checkx = actors[0].x + xmove;
  102.     if (TryMove(Checkx,actors[0].y)) {
  103.         actors[0].x = Checkx;    /* Set new x */
  104.         return;
  105.     }
  106.  
  107. /* try just vertical*/
  108.  
  109.     Checky = actors[0].y + ymove;
  110.     if (TryMove(actors[0].x,Checky)) {
  111.         actors[0].y = Checky;    /* Set new y */
  112.     }
  113. }
  114.  
  115. /**********************************
  116.  
  117.     Adds movement to xmove & ymove
  118.         
  119. **********************************/
  120.  
  121. static void Thrust(Word angle,Word speed,Word *xmove, Word *ymove)
  122. {    
  123.     angle &= ANGLES-1;        /* Mask the angle range */
  124.     if (speed >= TILEGLOBAL) {
  125.         speed = TILEGLOBAL-1;    /* Force maximum speed */
  126.     }
  127.     *xmove += FixedByFrac(speed,costable[angle]);    /* Add x motion */
  128.     *ymove -= FixedByFrac(speed,sintable[angle]);    /* Add y motion */
  129. }
  130.  
  131. /**********************************
  132.  
  133.     Changes the player's angle and position
  134.         
  135. **********************************/
  136.  
  137. #define TURNSPEED        4        /* Turning while moving */
  138. #define FASTTURN        6        /* Turning in place */
  139. #define WALKSPEED        25
  140. #define RUNSPEED        45
  141.  
  142. void ControlMovement(void)
  143. {
  144.     Word turn,total;
  145.     Word tile;
  146.     Word xmove,ymove;
  147.     Word move;
  148.     
  149.     playermoving = FALSE;    /* No motion (Yet) */
  150.     xmove = 0;                /* Init my deltas */
  151.     ymove = 0;
  152.     
  153.     if (buttonstate[bt_run]) {
  154.         turn = FASTTURN*TicCount;    /* Really fast turn */
  155.         move = RUNSPEED*TicCount;
  156.     } else {
  157.         turn = TURNSPEED*TicCount;    /* Moderate speed turn */
  158.         move = WALKSPEED*TicCount;
  159.     }
  160.  
  161. /* turning */
  162.  
  163.     gamestate.viewangle += mouseturn;        /* Add in the mouse movement verbatim */
  164.     
  165.     if (buttonstate[bt_east]) {
  166.         gamestate.viewangle -= turn;        /* Turn right */
  167.     }
  168.     if (buttonstate[bt_west]) {
  169.         gamestate.viewangle += turn;        /* Turn left */
  170.     }
  171.     gamestate.viewangle &= (ANGLES-1);        /* Fix the viewing angle */
  172.  
  173. /* Handle all strafe motion */
  174.  
  175.     if (mousex) {            /* Side to side motion (Strafe mode) */
  176.         mousex<<=3;
  177.         if (mousex>0) {
  178.             Thrust(gamestate.viewangle - ANGLES/4,mousex,&xmove,&ymove);
  179.         } else {
  180.             Thrust(gamestate.viewangle + ANGLES/4,-mousex,&xmove,&ymove);
  181.         }
  182.     }
  183.     if (buttonstate[bt_right]) {    /* Slide right keyboard */
  184.         Thrust(gamestate.viewangle - ANGLES/4, move>>1,&xmove,&ymove);
  185.     }
  186.     if (buttonstate[bt_left]) {        /* Slide left keyboard */
  187.         Thrust(gamestate.viewangle + ANGLES/4, move>>1,&xmove,&ymove);
  188.     }    
  189.     
  190. /* Handle all forward motion */
  191.  
  192.     total = buttonstate[bt_north] ? move : 0;    /* Move ahead? */
  193.     if (mousey < 0) {            /* Moved the mouse ahead? */
  194.         total -= mousey<<3;        /* Add it in */
  195.     }
  196.     if (total) {
  197.         Thrust(gamestate.viewangle, total,&xmove,&ymove);    /* Move ahead */
  198.     }
  199.     
  200.     total = buttonstate[bt_south] ? move : 0;    /* Reverse direction */
  201.     if (mousey > 0) {
  202.         total += mousey<<3;
  203.     }
  204.     if (total) {
  205.         Thrust(gamestate.viewangle+ANGLES/2, total,&xmove,&ymove);
  206.     }
  207.     mousex = 0;        
  208.     mousey = 0;        /* Reset the mouse motion */
  209.     mouseturn = 0;
  210.     
  211.     if (xmove || ymove) {    /* Any motion? */
  212.         ClipMove(xmove,ymove);    /* Move ahead (Clipped) */
  213.         tile = tilemap[actors[0].y>>FRACBITS][actors[0].x>>FRACBITS];
  214.         if (!(tile&TI_DOOR) ) {        /* Normal tile? */
  215.             actors[0].areanumber = tile & TI_NUMMASK;    /* Set my new area */
  216.         }
  217.     }
  218. }
  219.  
  220.